package com.battle.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.battle.pojo.entity.*;
import com.battle.pojo.param.questionBankStudy.*;
import com.battle.pojo.vo.examStudy.GetExamStudyVo;
import com.battle.pojo.vo.examStudyDetails.GetExamStudyDetailsListVo;
import com.battle.pojo.vo.examStudyDetails.GetExamStudyDetailsVo;
import com.battle.pojo.vo.questionBankDetailsStudy.GetQuestionBankDetailsStudyVo;
import com.battle.pojo.vo.questionBankStudy.*;
import com.battle.pojo.dto.questionBankStudy.*;
import com.battle.service.repository.in.QuestionBankDetailsRepository;
import com.battle.service.repository.in.QuestionBankDetailsStudyRepository;
import com.battle.service.repository.in.QuestionBankRepository;
import com.battle.service.repository.in.QuestionBankStudyRepository;
import com.battle.service.service.in.QuestionBankStudyService;
import com.google.gson.Gson;
import nirvana.core.domains.vo.PageResult;
import nirvana.core.exceptions.BizException;
import nirvana.core.utils.ids.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 【描 述】：题库学习服务
 * 【环 境】：J2SE 17
 * 【详 细】：
 */
@Service
public class QuestionBankStudyServiceImpl implements QuestionBankStudyService {

    private final QuestionBankStudyRepository questionBankStudyRepository;
    private final QuestionBankDetailsStudyRepository bankDetailsStudyRepository;
    private final QuestionBankRepository bankRepository;
    private final QuestionBankDetailsRepository bankDetailsRepository;

    public QuestionBankStudyServiceImpl(QuestionBankStudyRepository questionBankStudyRepository, QuestionBankDetailsStudyRepository bankDetailsStudyRepository, QuestionBankRepository bankRepository, QuestionBankDetailsRepository bankDetailsRepository) {
        this.questionBankStudyRepository = questionBankStudyRepository;
        this.bankDetailsStudyRepository = bankDetailsStudyRepository;
        this.bankRepository = bankRepository;
        this.bankDetailsRepository = bankDetailsRepository;
    }


    /**
     * 创建题库学习
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createQuestionBankStudy(CreateQuestionBankStudyParam param) {
        Gson gson = new Gson();

        //根据用户id和试卷id查找未完成的考试
        List<QuestionBankStudy> examStudies = questionBankStudyRepository.getBaseMapper().selectList(
                new LambdaQueryWrapper<>(QuestionBankStudy.class)
                        .eq(QuestionBankStudy::getUserId, param.getUserId())
                        .eq(QuestionBankStudy::getQuestionBankId, param.getQuestionBankId())
                        .eq(QuestionBankStudy::getStatus, 0));
        if (CollectionUtil.isNotEmpty(examStudies)) {
            GetQuestionBankStudyVo examStudy = getQuestionBankStudy(examStudies.get(0).getId());
            return examStudy.getBankStudyId();
        }

        List<GetQuestionBankDetailsStudyVo> detailsVoList = new ArrayList<>();

        QuestionBankStudy questionBankStudy = new QuestionBankStudy();
        BeanUtils.copyProperties(param, questionBankStudy);
        Long id = IdGenerator.SNOW.generate();
        questionBankStudy.setId(id);
        questionBankStudy.setStatus(0);

        //查询题库id
        QuestionBank bank = bankRepository.getByIdCheck(param.getQuestionBankId());
        questionBankStudy.setTypeId(bank.getTypeId());

        List<QuestionBankDetailsStudy> detailsStudyList = new ArrayList<>();
        //根据题库id获取题目列表
        List<QuestionBankDetails> questionBankDetailsList = bankDetailsRepository.getListByBankId(param.getQuestionBankId());
        if (CollectionUtil.isNotEmpty(questionBankDetailsList)) {
            for (QuestionBankDetails questionBankDetails : questionBankDetailsList) {
                QuestionBankDetailsStudy detailsStudy = new QuestionBankDetailsStudy();
                BeanUtils.copyProperties(questionBankDetails, detailsStudy);
                detailsStudy.setQuestionBankStudyId(id);
                detailsStudy.setQuestionId(questionBankDetails.getId());
                detailsStudy.setBankAnswer(questionBankDetails.getAnswer());
                detailsStudy.setStatus(0);
                detailsStudy.setId(IdGenerator.SNOW.generate());
                detailsStudy.setUserId(param.getUserId());
                detailsStudyList.add(detailsStudy);

                GetQuestionBankDetailsStudyVo detailsVo = new GetQuestionBankDetailsStudyVo();
                BeanUtils.copyProperties(detailsStudy, detailsVo);
                List<String> bankAnswerJson = JSONArray.parseArray(detailsStudy.getBankAnswer(), String.class);
                Map<String, String> optionJson = gson.fromJson(detailsStudy.getOptions(), Map.class);
                detailsVo.setBankAnswerJson(bankAnswerJson);
                detailsVo.setBankStudyId(id);
                detailsVo.setOptionsJson(optionJson);
                detailsVoList.add(detailsVo);
            }
            if (!bankDetailsStudyRepository.saveBatch(detailsStudyList)) {
                throw new BizException("创建用户题库学习详情失败");
            }
        }

        questionBankStudy.setNeedFinishQuestionNum(detailsVoList.size());
        questionBankStudyRepository.create(questionBankStudy);
        return questionBankStudy.getId();
    }

    /**
     * 修改题库学习
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editQuestionBankStudy(EditQuestionBankStudyParam param) {
        Long id = param.getId();
        QuestionBankStudy questionBankStudy = questionBankStudyRepository.getByIdCheck(param.getBankStudyId());

        int finishQuestionNum = 0;
        List<QuestionBankDetailsStudy> questionBankDetailsList = bankDetailsStudyRepository.getQuestionBankDetailsStudyList(param.getBankStudyId());
        for (QuestionBankDetailsStudy studyDetails : questionBankDetailsList) {

            if (id.equals(studyDetails.getId())) {
                studyDetails.setStatus(1);
                String userAnswer = JSONArray.toJSONString(param.getUserAnswer());
                studyDetails.setUserAnswer(userAnswer);
                //计算是否回答正确
                Boolean equalsAnswer = equalsAnswer(param.getUserAnswer(), studyDetails.getBankAnswer());
                studyDetails.setIsCorrect(equalsAnswer);
                if (!bankDetailsStudyRepository.edit(studyDetails)) {
                    throw new BizException("修改用户题库详情失败");
                }
            }
            //如果是已经完成的题目
            if (studyDetails.getStatus() == 1) {
                finishQuestionNum++;

            }
        }
        questionBankStudy.setStatus(finishQuestionNum == questionBankDetailsList.size() ? 1 : 0);
        questionBankStudy.setFinishQuestionNum(finishQuestionNum);
        questionBankStudyRepository.edit(questionBankStudy);
    }

    Boolean equalsAnswer(List<String> userAnswer, String answer) {
        //1.将两边答案转换成数组
        List<String> answerList = JSONArray.parseArray(answer, String.class);
        //2.将两边答案排序
        userAnswer.sort(String::compareTo);
        answerList.sort(String::compareTo);
        //3.比较两边答案是否一致
        return userAnswer.equals(answerList);
    }

    /**
     * 移除题库学习
     *
     * @param id
     */
    @Override
    public void removeQuestionBankStudy(Long id) {
        questionBankStudyRepository.removeById(id);
    }

    /**
     * 启动/禁用题库学习
     *
     * @param id
     */
    @Override
    public void enabledQuestionBankStudy(Long id) {
        QuestionBankStudy questionBankStudy = questionBankStudyRepository.getByIdCheck(id);
        questionBankStudy.setIsDisable(!questionBankStudy.getIsDisable());
        questionBankStudyRepository.edit(questionBankStudy);
    }

    /**
     * 获取题库学习详情
     *
     * @param id
     * @return
     */
    @Override
    public GetQuestionBankStudyVo getQuestionBankStudy(Long id) {
        QuestionBankStudy questionBankStudy = questionBankStudyRepository.getByIdCheck(id);
        GetQuestionBankStudyVo vo = new GetQuestionBankStudyVo();
        BeanUtils.copyProperties(questionBankStudy, vo);
        vo.setBankStudyId(questionBankStudy.getId());

        //完整的题目情况
        List<GetQuestionBankDetailsStudyVo> detailsVoList=new ArrayList<>();
        //题目状态
        List<GetExamStudyDetailsListVo> statusList=new ArrayList<>();

        //根据题库学习id获取题目列表
        List<QuestionBankDetailsStudy> questionBankDetailsList = bankDetailsStudyRepository.getQuestionBankDetailsStudyList(id);
        if (CollectionUtil.isNotEmpty(questionBankDetailsList)) {
            for (QuestionBankDetailsStudy questionBankDetails : questionBankDetailsList) {
                GetQuestionBankDetailsStudyVo detailsVo = new GetQuestionBankDetailsStudyVo();
                BeanUtils.copyProperties(questionBankDetails, detailsVo);

                List<String> bankAnswerJson = JSONArray.parseArray(questionBankDetails.getBankAnswer(), String.class);
                Map<String, String> optionJson = new Gson().fromJson(questionBankDetails.getOptions(), Map.class);
                detailsVo.setBankAnswerJson(bankAnswerJson);
                detailsVo.setOptionsJson(optionJson);
                detailsVo.setBankStudyId(questionBankDetails.getQuestionBankStudyId());
                detailsVoList.add(detailsVo);

                GetExamStudyDetailsListVo statusVo = new GetExamStudyDetailsListVo();
                statusVo.setId(questionBankDetails.getId());
                //判断题目是否正确
                if (questionBankDetails.getStatus() == 0) {
                    statusVo.setStatus(2);
                } else {
                    statusVo.setStatus(questionBankDetails.getIsCorrect() ? 0 : 1);
                }
                statusList.add(statusVo);
            }
        }
        vo.setStatusList(statusList);
        vo.setDetailsVoList(detailsVoList);
        return vo;
    }

    /**
     * 根据id获取题库题目详情
     * @param id
     * @return
     */
    @Override
    public GetQuestionBankDetailsStudyVo getQuestionBankDetailsStudy(Long id) {
        GetQuestionBankDetailsStudyVo vo=new GetQuestionBankDetailsStudyVo();
        QuestionBankDetailsStudy details = bankDetailsStudyRepository.getByIdCheck(id);
        BeanUtils.copyProperties(details, vo);

        List<String> bankAnswerJson = JSONArray.parseArray(details.getBankAnswer(),String.class);
        Map<String,String> optionJson = new Gson().fromJson(details.getOptions(), Map.class);

        vo.setBankAnswerJson(bankAnswerJson);
        vo.setOptionsJson(optionJson);
        vo.setBankStudyId(details.getQuestionBankStudyId());

        return vo;
    }

    /**
     * 获取题库学习 列表
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<GetQuestionBankStudyListVo> getQuestionBankStudyList(GetQuestionBankStudyListParam param) {

        SelectQuestionBankStudyDto dto = new SelectQuestionBankStudyDto();
        BeanUtils.copyProperties(param, dto);
        Page<QuestionBankStudy> page = questionBankStudyRepository.selectQuestionBankStudy(dto);
        List<QuestionBankStudy> questionBankStudyList = page.getRecords();
        List<GetQuestionBankStudyListVo> list = new ArrayList<>();
        for (QuestionBankStudy questionBankStudy : questionBankStudyList) {
            GetQuestionBankStudyListVo vo = new GetQuestionBankStudyListVo();
            BeanUtils.copyProperties(questionBankStudy, vo);

            list.add(vo);
        }
        return new PageResult<>(list, page);

    }

    /**
     * 获取题库学习下拉列表
     *
     * @param param
     * @return
     */
    @Override
    public List<GetQuestionBankStudyDownListVo> getQuestionBankStudyDownList(GetQuestionBankStudyDownListParam param) {
        QuestionBankStudy po = new QuestionBankStudy();
        if (param != null) {
            BeanUtils.copyProperties(param, po);
        }
        List<QuestionBankStudy> questionBankStudyList = questionBankStudyRepository.getListByEntity(po);

        List<GetQuestionBankStudyDownListVo> list = new ArrayList<>();
        for (QuestionBankStudy questionBankStudy : questionBankStudyList) {
            GetQuestionBankStudyDownListVo vo = new GetQuestionBankStudyDownListVo();
            BeanUtils.copyProperties(questionBankStudy, vo);
            list.add(vo);
        }
        return list;
    }


}



